using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using System.Diagnostics;

namespace _1945
{
    /// <summary>
    /// Handles enemies spawning.
    /// </summary>
    public class EnemySpawner : GameComponent
    {

        private struct enemyMiniWave
        {
            TimeSpan timeActive;
            public TimeSpan TimeActive { get { return timeActive; } set { timeActive = value; } }
            List<Enemy> enemyGroup;
            public List<Enemy> EnemyGroup { get { return enemyGroup; } set { enemyGroup = value; } }

            public enemyMiniWave(TimeSpan timeActive, List<Enemy> enemyGroup) 
            {
                this.timeActive = timeActive;
                this.enemyGroup = enemyGroup;
            }

            /// <summary>
            /// Returns a clone (deepcopy) of the current object
            /// </summary>
            /// <returns></returns>
            public enemyMiniWave clone()
            {
                List<Enemy> enemyGroupClone = new List<Enemy>();
                foreach (Enemy e in enemyGroup)
                {
                    enemyGroupClone.Add(e.clone());
                }
                return new enemyMiniWave(timeActive, enemyGroupClone);
            }
            
        }

        //return active list
        //check which list
        //change list
        //spawn boss
        //base.Update(gameTime);
        
        private SpriteFactory spriteFactory;
        private List<GameObject> enemyBullets;
        private List<Enemy> enemies;
        private List<GameObject> islands;
        private Random rand;
        private Texture2D gameSpriteSheet;
        private Rectangle gameScreenBounds;
        private List<enemyMiniWave> enemyMiniWaveList = new List<enemyMiniWave>();
        private int currentMiniWave = 0;
        private TimeSpan lastMiniWave = TimeSpan.Zero;

        private enemyMiniWave threeStraightDownFromLeft = new enemyMiniWave(TimeSpan.Zero, new List<Enemy>());
        private enemyMiniWave threeStraightDownFromMiddle = new enemyMiniWave(TimeSpan.Zero, new List<Enemy>());
        private enemyMiniWave threeStraightDownFromRight = new enemyMiniWave(TimeSpan.Zero, new List<Enemy>());
        private enemyMiniWave fiveStraightDownSeparateLRFromMiddle = new enemyMiniWave(TimeSpan.Zero, new List<Enemy>());
        private enemyMiniWave twoDiagonalFromCorner = new enemyMiniWave(TimeSpan.Zero, new List<Enemy>());
        private enemyMiniWave threeStraightDownConvergeMiddleFromLeft = new enemyMiniWave(TimeSpan.Zero, new List<Enemy>());
        private enemyMiniWave threeStraightDownConvergeMiddleFromRight = new enemyMiniWave(TimeSpan.Zero, new List<Enemy>());
        private enemyMiniWave oneDownLeftDownFromRight = new enemyMiniWave(TimeSpan.Zero, new List<Enemy>());
        private enemyMiniWave oneDownRightDownFromLeft = new enemyMiniWave(TimeSpan.Zero, new List<Enemy>());
        private enemyMiniWave boss = new enemyMiniWave(TimeSpan.Zero, new List<Enemy>());

        private float startY = -32;
        private int enemyWidth = 32;
        private int enemyDistance = 15;

        private Sprite bulletSmall;
        private Sprite bulletBig;
        private Sprite bulletDoubleDown;

        private Sprite enemy_DF_A_small_Gray; 
        private Sprite enemy_DF_A_small_White;
        private Sprite enemy_DF_A_small_Green;
        private Sprite enemy_DF_A_small_Blue;
        private Sprite enemy_DF_A_small_Orange;
        private Sprite enemy_UF_A_big_Military_Camouflage;

        private Vector2 startPosThreeLeftOne;    
        private Vector2 startPosThreeLeftTwo; 
        private Vector2 startPosThreeLeftThree;
        private Vector2 startPosThreeMiddleOne;
        private Vector2 startPosThreeMiddleTwo;
        private Vector2 startPosThreeMiddleThree;
        private Vector2 startPosThreeRightOne;
        private Vector2 startPosThreeRightTwo;
        private Vector2 startPosThreeRightThree;
        private Vector2 startPosFiveMiddleOne;
        private Vector2 startPosFiveMiddleTwo;
        private Vector2 startPosFiveMiddleThree;
        private Vector2 startPosFiveMiddleFour;
        private Vector2 startPosFiveMiddleFive;

        private MovementPattern mp_straightDown;
        private MovementPattern mp_straightDownSeparateLeft;
        private MovementPattern mp_straightDownSeparateRight;
        private MovementPattern mp_diagonalFromLeft;
        private MovementPattern mp_diagonalFromRight;
        private MovementPattern mp_straightDownConvergeMiddleFromLeftOne;
        private MovementPattern mp_straightDownConvergeMiddleFromLeftTwo;
        private MovementPattern mp_straightDownConvergeMiddleFromLeftThree;
        private MovementPattern mp_straightDownConvergeMiddleFromRightOne;
        private MovementPattern mp_straightDownConvergeMiddleFromRightTwo;
        private MovementPattern mp_straightDownConvergeMiddleFromRightThree;
        private MovementPattern mp_downRightDownFromLeft;
        private MovementPattern mp_downLeftDownFromRight;
        private MovementPattern mp_boss;


        public EnemySpawner(Game game, List<Enemy> enemies, List<GameObject> enemyBullets, List<GameObject> islands, Texture2D gameSpriteSheet, Rectangle gameScreenBounds)
            :base(game)
        {
            spriteFactory = (SpriteFactory)game.Services.GetService(typeof(SpriteFactory));
            this.enemyBullets = enemyBullets;
            this.enemies = enemies;
            this.islands = islands;
            rand = new Random((int)DateTime.Now.Ticks);
            this.gameSpriteSheet = gameSpriteSheet;
            this.gameScreenBounds = gameScreenBounds;

            createMiniWaves();

        }

        private void createMiniWaves()
        {
            //Bullet sprites
            bulletSmall         = spriteFactory.getBulletSprite(SpriteFactory.bullets.smallBullet);
            bulletBig           = spriteFactory.getBulletSprite(SpriteFactory.bullets.bigBullet);
            bulletDoubleDown    = spriteFactory.getBulletSprite(SpriteFactory.bullets.downdouble);

            //Enemy sprites
            enemy_DF_A_small_Blue   = spriteFactory.getEnemySprite(SpriteFactory.enemies.DF_A_small_Blue);
            enemy_DF_A_small_Gray   = spriteFactory.getEnemySprite(SpriteFactory.enemies.DF_A_small_Gray);
            enemy_DF_A_small_Green  = spriteFactory.getEnemySprite(SpriteFactory.enemies.DF_A_small_Green);
            enemy_DF_A_small_Orange = spriteFactory.getEnemySprite(SpriteFactory.enemies.DF_A_small_Orange);
            enemy_DF_A_small_White  = spriteFactory.getEnemySprite(SpriteFactory.enemies.DF_A_small_White);
            enemy_UF_A_big_Military_Camouflage = spriteFactory.getEnemySprite(SpriteFactory.enemies.UF_A_big_Military_Camouflage);
            
            //Start positions
            startPosThreeLeftOne    = new Vector2(enemyDistance, startY);    
            startPosThreeLeftTwo    = new Vector2(startPosThreeLeftOne.X + enemyWidth + enemyDistance, startY);
            startPosThreeLeftThree  = new Vector2(startPosThreeLeftTwo.X + enemyWidth + enemyDistance, startY);
            startPosThreeMiddleOne  = new Vector2(gameScreenBounds.Width / 2 - (3 * enemyWidth + 2 * enemyDistance) / 2, startY);
            startPosThreeMiddleTwo  = new Vector2(startPosThreeMiddleOne.X + enemyWidth + enemyDistance, startY);
            startPosThreeMiddleThree= new Vector2(startPosThreeMiddleTwo.X + enemyWidth + enemyDistance, startY);
            startPosThreeRightOne   = new Vector2(gameScreenBounds.Width - 3 * (enemyWidth + enemyDistance), startY);
            startPosThreeRightTwo   = new Vector2(startPosThreeRightOne.X + enemyWidth + enemyDistance, startY);
            startPosThreeRightThree = new Vector2(startPosThreeRightTwo.X + enemyWidth + enemyDistance, startY);
            startPosFiveMiddleOne   = new Vector2(gameScreenBounds.Width / 2 - (5 * enemyWidth + 4 * enemyDistance) / 2, startY);
            startPosFiveMiddleTwo   = new Vector2(startPosFiveMiddleOne.X + enemyWidth + enemyDistance, startY);
            startPosFiveMiddleThree = new Vector2(startPosFiveMiddleTwo.X + enemyWidth + enemyDistance, startY);
            startPosFiveMiddleFour  = new Vector2(startPosFiveMiddleThree.X + enemyWidth + enemyDistance, startY);
            startPosFiveMiddleFive  = new Vector2(startPosFiveMiddleFour.X + enemyWidth + enemyDistance, startY);

            //Movement patterns
            mp_straightDown                             = new MovementPattern(MovementPattern.DirectionalPattern.straightdown);
            mp_straightDownSeparateLeft                 = new MovementPattern(new Vector2[2]{new Vector2(startPosFiveMiddleOne.X, gameScreenBounds.Height * 0.5f), new Vector2(0, gameScreenBounds.Height + 50)}, new TimeSpan[1]{TimeSpan.Zero}, false);
            mp_straightDownSeparateRight                = new MovementPattern(new Vector2[2]{new Vector2(startPosFiveMiddleFive.X, gameScreenBounds.Height * 0.5f), new Vector2(gameScreenBounds.Width, gameScreenBounds.Height + 50) }, new TimeSpan[1] { TimeSpan.Zero }, false);
            mp_diagonalFromLeft                         = new MovementPattern(MovementPattern.DirectionalPattern.downright);
            mp_diagonalFromRight                        = new MovementPattern(MovementPattern.DirectionalPattern.downleft);
            mp_straightDownConvergeMiddleFromLeftOne    = new MovementPattern(new Vector2[2]{new Vector2(startPosThreeLeftOne.X, gameScreenBounds.Height * 0.5f), new Vector2(gameScreenBounds.Width, gameScreenBounds.Height + 50)}, new TimeSpan[1]{TimeSpan.Zero}, false);
            mp_straightDownConvergeMiddleFromLeftTwo    = new MovementPattern(new Vector2[2]{new Vector2(startPosThreeLeftTwo.X, gameScreenBounds.Height * 0.5f), new Vector2(gameScreenBounds.Width, gameScreenBounds.Height + 50)}, new TimeSpan[1]{TimeSpan.Zero}, false);
            mp_straightDownConvergeMiddleFromLeftThree  = new MovementPattern(new Vector2[2]{new Vector2(startPosThreeLeftThree.X, gameScreenBounds.Height * 0.5f), new Vector2(gameScreenBounds.Width, gameScreenBounds.Height + 50) }, new TimeSpan[1] { TimeSpan.Zero }, false);
            mp_straightDownConvergeMiddleFromRightOne   = new MovementPattern(new Vector2[2]{new Vector2(startPosThreeRightOne.X, gameScreenBounds.Height * 0.5f), new Vector2(0, gameScreenBounds.Height + 50)}, new TimeSpan[1]{TimeSpan.Zero}, false);    
            mp_straightDownConvergeMiddleFromRightTwo   = new MovementPattern(new Vector2[2]{new Vector2(startPosThreeRightTwo.X, gameScreenBounds.Height * 0.5f), new Vector2(0, gameScreenBounds.Height + 50)}, new TimeSpan[1]{TimeSpan.Zero}, false);
            mp_straightDownConvergeMiddleFromRightThree = new MovementPattern(new Vector2[2]{new Vector2(startPosThreeRightThree.X, gameScreenBounds.Height * 0.5f), new Vector2(0, gameScreenBounds.Height + 50) }, new TimeSpan[1]{TimeSpan.Zero}, false);
            mp_downRightDownFromLeft                    = new MovementPattern(new Vector2[3]{new Vector2(startPosThreeLeftOne.X, gameScreenBounds.Height * 0.3f), new Vector2(gameScreenBounds.Width * 0.85f, gameScreenBounds.Height * 0.7f), new Vector2(gameScreenBounds.Width * 0.85f, gameScreenBounds.Height + 50) }, new TimeSpan[2] { new TimeSpan(0, 0, 2), new TimeSpan(0, 0, 2) }, false);
            mp_downLeftDownFromRight                    = new MovementPattern(new Vector2[3]{new Vector2(startPosThreeRightThree.X, gameScreenBounds.Height * 0.3f), new Vector2(gameScreenBounds.Width * 0.15f, gameScreenBounds.Height * 0.7f), new Vector2(gameScreenBounds.Width * 0.15f, gameScreenBounds.Height + 50) }, new TimeSpan[2] { new TimeSpan(0, 0, 2), new TimeSpan(0, 0, 2) }, false);
            
            Vector2 middle = new Vector2(gameScreenBounds.Width / 2 - 40, gameScreenBounds.Height /2 - 40);
            Vector2 upLeft = new Vector2(gameScreenBounds.Width / 6 - 40, gameScreenBounds.Height / 6 - 40);
            Vector2 downLeft = new Vector2(gameScreenBounds.Width / 6 - 40, gameScreenBounds.Height / 6 * 5 + 40);
            Vector2 upRight = new Vector2(gameScreenBounds.Width / 6 * 5 + 40, gameScreenBounds.Height / 6 - 40);
            Vector2 downMiddle = new Vector2(gameScreenBounds.Width / 2 - 40, gameScreenBounds.Height / 6 * 5 + 40);
            TimeSpan[] bossWait = new TimeSpan[8];
            for (int i = 0; i < bossWait.Count(); i++)
            {
                bossWait[i] = new TimeSpan(0, 0, 0, 3);
            }

            mp_boss  = new MovementPattern(new Vector2[8] { middle, upLeft, downLeft, upRight, downMiddle, upLeft, upRight, middle }, bossWait, true); 
            
            threeStraightDownFromLeft.TimeActive = new TimeSpan(0, 0, 0, 0, 3000);
            threeStraightDownFromLeft.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 10, 60, false, startPosThreeLeftOne, new Vector2(2), 1, false, 10, enemy_DF_A_small_Blue, gameScreenBounds, bulletSmall, enemyBullets, mp_straightDown));
            threeStraightDownFromLeft.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 10, 60, false, startPosThreeLeftTwo, new Vector2(2), 1, false, 10, enemy_DF_A_small_Blue, gameScreenBounds, bulletSmall, enemyBullets, mp_straightDown));
            threeStraightDownFromLeft.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 10, 60, false, startPosThreeLeftThree, new Vector2(2), 1, false, 10, enemy_DF_A_small_Blue, gameScreenBounds, bulletSmall, enemyBullets, mp_straightDown));

            threeStraightDownFromMiddle.TimeActive = new TimeSpan(0, 0, 0, 0, 3000);
            threeStraightDownFromMiddle.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 10, 60, false, startPosThreeMiddleOne, new Vector2(2), 1, false, 10, enemy_DF_A_small_Gray, gameScreenBounds, bulletSmall, enemyBullets, mp_straightDown));
            threeStraightDownFromMiddle.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 10, 60, false, startPosThreeMiddleTwo, new Vector2(2), 1, false, 10, enemy_DF_A_small_Gray, gameScreenBounds, bulletSmall, enemyBullets, mp_straightDown));
            threeStraightDownFromMiddle.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 10, 60, false, startPosThreeMiddleThree, new Vector2(2), 1, false, 10, enemy_DF_A_small_Gray, gameScreenBounds, bulletSmall, enemyBullets, mp_straightDown));

            threeStraightDownFromRight.TimeActive = new TimeSpan(0, 0, 0, 0, 3000);
            threeStraightDownFromRight.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 10, 60, false, startPosThreeRightOne, new Vector2(2), 1, false, 10, enemy_DF_A_small_Green, gameScreenBounds, bulletSmall, enemyBullets, mp_straightDown));
            threeStraightDownFromRight.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 10, 60, false, startPosThreeRightTwo, new Vector2(2), 1, false, 10, enemy_DF_A_small_Green, gameScreenBounds, bulletSmall, enemyBullets, mp_straightDown));
            threeStraightDownFromRight.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 10, 60, false, startPosThreeRightThree, new Vector2(2), 1, false, 10, enemy_DF_A_small_Green, gameScreenBounds, bulletSmall, enemyBullets, mp_straightDown));

            fiveStraightDownSeparateLRFromMiddle.TimeActive = new TimeSpan(0, 0, 0, 0, 6500);
            fiveStraightDownSeparateLRFromMiddle.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 20, 60, false, startPosFiveMiddleOne, new Vector2(2), 1, false, 20, enemy_DF_A_small_Orange, gameScreenBounds, bulletBig, enemyBullets, mp_straightDownSeparateLeft));
            fiveStraightDownSeparateLRFromMiddle.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 20, 60, false, startPosFiveMiddleTwo, new Vector2(2), 1, false, 20, enemy_DF_A_small_Orange, gameScreenBounds, bulletBig, enemyBullets, mp_straightDown));
            fiveStraightDownSeparateLRFromMiddle.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 20, 60, false, startPosFiveMiddleThree, new Vector2(2), 1, false, 20, enemy_DF_A_small_Orange, gameScreenBounds, bulletBig, enemyBullets, mp_straightDown));
            fiveStraightDownSeparateLRFromMiddle.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 20, 60, false, startPosFiveMiddleFour, new Vector2(2), 1, false, 20, enemy_DF_A_small_Orange, gameScreenBounds, bulletBig, enemyBullets, mp_straightDown));
            fiveStraightDownSeparateLRFromMiddle.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 20, 60, false, startPosFiveMiddleFive, new Vector2(2), 1, false, 20, enemy_DF_A_small_Orange, gameScreenBounds, bulletBig, enemyBullets, mp_straightDownSeparateRight));
            
            twoDiagonalFromCorner.TimeActive = new TimeSpan(0, 0, 0, 0, 3000);
            twoDiagonalFromCorner.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 30, 60, false, startPosThreeLeftOne, new Vector2(2), 1, false, 30, enemy_DF_A_small_White, gameScreenBounds, bulletDoubleDown, enemyBullets, mp_diagonalFromLeft));
            twoDiagonalFromCorner.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 30, 60, false, startPosThreeRightThree, new Vector2(2), 1, false, 30, enemy_DF_A_small_White, gameScreenBounds, bulletDoubleDown, enemyBullets, mp_diagonalFromRight));

            threeStraightDownConvergeMiddleFromRight.TimeActive = new TimeSpan(0, 0, 0, 0, 4500);
            threeStraightDownConvergeMiddleFromRight.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 20, 60, false, startPosThreeRightOne, new Vector2(2), 1, false, 10, enemy_DF_A_small_Green, gameScreenBounds, bulletSmall, enemyBullets, mp_straightDownConvergeMiddleFromRightOne));
            threeStraightDownConvergeMiddleFromRight.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 20, 60, false, startPosThreeRightTwo, new Vector2(2), 1, false, 10, enemy_DF_A_small_Green, gameScreenBounds, bulletSmall, enemyBullets, mp_straightDownConvergeMiddleFromRightTwo));
            threeStraightDownConvergeMiddleFromRight.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 20, 60, false, startPosThreeRightThree, new Vector2(2), 1, false, 10, enemy_DF_A_small_Green, gameScreenBounds, bulletSmall, enemyBullets, mp_straightDownConvergeMiddleFromRightThree));
            
            threeStraightDownConvergeMiddleFromLeft.TimeActive = new TimeSpan(0, 0, 0, 0, 4500);
            threeStraightDownConvergeMiddleFromLeft.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 20, 60, false, startPosThreeLeftOne, new Vector2(2), 1, false, 10, enemy_DF_A_small_Blue, gameScreenBounds, bulletSmall, enemyBullets, mp_straightDownConvergeMiddleFromLeftOne));
            threeStraightDownConvergeMiddleFromLeft.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 20, 60, false, startPosThreeLeftTwo, new Vector2(2), 1, false, 10, enemy_DF_A_small_Blue, gameScreenBounds, bulletSmall, enemyBullets, mp_straightDownConvergeMiddleFromLeftTwo));
            threeStraightDownConvergeMiddleFromLeft.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 20, 60, false, startPosThreeLeftThree, new Vector2(2), 1, false, 10, enemy_DF_A_small_Blue, gameScreenBounds, bulletSmall, enemyBullets, mp_straightDownConvergeMiddleFromLeftThree));

            oneDownRightDownFromLeft.TimeActive = new TimeSpan(0, 0, 0, 0, 2500);
            oneDownRightDownFromLeft.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 10, 60, false, startPosThreeLeftOne, new Vector2(2), 1, false, 30, enemy_DF_A_small_White, gameScreenBounds, bulletDoubleDown, enemyBullets, mp_downRightDownFromLeft));

            oneDownLeftDownFromRight.TimeActive = new TimeSpan(0, 0, 0, 0, 2500);
            oneDownLeftDownFromRight.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, false, 10, 60, false, startPosThreeRightThree, new Vector2(2), 1, false, 30, enemy_DF_A_small_White, gameScreenBounds, bulletDoubleDown, enemyBullets, mp_downLeftDownFromRight));

            boss.EnemyGroup.Add(new Enemy(Game, gameSpriteSheet, true, 100, 1000, true, new Vector2(gameScreenBounds.Width / 2 - 50, -50), new Vector2(4), 2, false, 40, enemy_UF_A_big_Military_Camouflage, gameScreenBounds, bulletBig, enemyBullets, mp_boss));

            enemyMiniWaveList.Add(twoDiagonalFromCorner.clone());
            enemyMiniWaveList.Add(fiveStraightDownSeparateLRFromMiddle.clone());
            enemyMiniWaveList.Add(twoDiagonalFromCorner.clone());
            enemyMiniWaveList.Add(oneDownLeftDownFromRight.clone());
            enemyMiniWaveList.Add(threeStraightDownConvergeMiddleFromRight.clone());
            enemyMiniWaveList.Add(oneDownLeftDownFromRight.clone());
            enemyMiniWaveList.Add(fiveStraightDownSeparateLRFromMiddle.clone());
            enemyMiniWaveList.Add(oneDownRightDownFromLeft.clone());
            enemyMiniWaveList.Add(threeStraightDownConvergeMiddleFromLeft.clone());
            enemyMiniWaveList.Add(fiveStraightDownSeparateLRFromMiddle.clone());
            enemyMiniWaveList.Add(twoDiagonalFromCorner.clone());
            enemyMiniWaveList.Add(oneDownRightDownFromLeft.clone());
            enemyMiniWaveList.Add(threeStraightDownConvergeMiddleFromRight.clone());
            enemyMiniWaveList.Add(threeStraightDownFromLeft.clone());
            enemyMiniWaveList.Add(threeStraightDownFromRight.clone());
            enemyMiniWaveList.Add(threeStraightDownConvergeMiddleFromLeft.clone());
            enemyMiniWaveList.Add(twoDiagonalFromCorner.clone());
            enemyMiniWaveList.Add(threeStraightDownConvergeMiddleFromRight.clone());
            enemyMiniWaveList.Add(fiveStraightDownSeparateLRFromMiddle.clone());
            enemyMiniWaveList.Add(twoDiagonalFromCorner.clone());
            enemyMiniWaveList.Add(oneDownLeftDownFromRight.clone());
            enemyMiniWaveList.Add(threeStraightDownConvergeMiddleFromRight.clone());
            enemyMiniWaveList.Add(oneDownLeftDownFromRight.clone());
            enemyMiniWaveList.Add(threeStraightDownConvergeMiddleFromRight.clone());
            enemyMiniWaveList.Add(oneDownLeftDownFromRight.clone());
            enemyMiniWaveList.Add(fiveStraightDownSeparateLRFromMiddle.clone());
            enemyMiniWaveList.Add(oneDownRightDownFromLeft.clone());
            enemyMiniWaveList.Add(threeStraightDownConvergeMiddleFromLeft.clone());

            enemyMiniWave lastWave = threeStraightDownFromMiddle.clone();
            lastWave.TimeActive = new TimeSpan(0, 0, 15);
            enemyMiniWaveList.Add(lastWave);
            enemyMiniWaveList.Add(boss);
        }

        public override void Update(GameTime gameTime)
        {
            
            Debug.Print("currentminiwave: " + currentMiniWave);
            if (rand.Next(1, 200) == 10 && currentMiniWave != enemyMiniWaveList.Count -1)
            {
                Enemy enemy = new Enemy(Game, gameSpriteSheet, false, 7, rand.Next(10, 41), false, new Vector2(rand.Next(0, gameScreenBounds.Width - 32), -32), new Vector2(rand.Next(1, 3)), 1, false, rand.Next(10, 41), spriteFactory.getEnemySprite(((SpriteFactory.enemies)(rand.Next(1, 6)))), gameScreenBounds, spriteFactory.getBulletSprite(SpriteFactory.bullets.smallBullet), enemyBullets, new MovementPattern(((MovementPattern.DirectionalPattern)rand.Next(1, 6))));
                enemies.Add(enemy);
            }

            if (gameTime.TotalGameTime.Subtract(lastMiniWave).CompareTo(enemyMiniWaveList[currentMiniWave].TimeActive) > 0)
            {
                //waited the TimeActive time of the current mini wave
                if (currentMiniWave < enemyMiniWaveList.Count -1)
                {
                    //we haven't run through the list yet
                    currentMiniWave++;
                    lastMiniWave = gameTime.TotalGameTime;

                    for (int i = 0; i < enemyMiniWaveList[currentMiniWave].EnemyGroup.Count; i++)
                    {
                        //launch all enemies in the current miniwave of the enemyminiwavelist
                        enemies.Add(enemyMiniWaveList[currentMiniWave].EnemyGroup[i]);
                    }
                }
            }
            
            base.Update(gameTime);
        }

    }
}
